package zheezes.eisp.collect.model.impl.gd;

import java.util.Calendar;
import java.util.List;

import org.apache.log4j.Logger;

import zheezes.eisp.collect.model.VipFrozenCollectTaskHandler;
import zheezes.eisp.data.orm.Concentrator;
import zheezes.eisp.data.orm.ResMeter;
import zheezes.eisp.data.orm.VipFrozenDataPo;
import zheezes.protocol.Frame;
import zheezes.protocol.impl.gd.Ctrl13Frame;
import zheezes.protocol.impl.gd.Ctrl93Frame;
import zheezes.protocol.impl.gd.GdConAddr;
import zheezes.protocol.impl.gd.bean.VipMeterData;
import zheezes.socket.Transput;
import zheezes.util.ArrayUtil;


public class GdVipFrozenCollectTaskHandler extends VipFrozenCollectTaskHandler {
	private static Logger logger = Logger.getLogger(GdVipFrozenCollectTaskHandler.class);
	
	static {
		logger.debug("loading");
	}

	@SuppressWarnings("unused")
	public void run() {
		List<ResMeter> list = query();
		Concentrator con = dataAccessor.getConById(task.getConId());
		Calendar cal = Calendar.getInstance();
		cal.setTime(task.getDataDate());
		int scnt = 0;
		int failCnt = 0;
		
		for (int i = 0; i < list.size() && !terminated; i++) {
			ResMeter meter = list.get(i);
			Ctrl13Frame frame = new Ctrl13Frame();
			frame.setRtua(new GdConAddr(con.getLogicAddr()));
			short start = meter.getSeq().shortValue();
			byte resend = 0x01;
			byte amount = 1;
			byte days = 1;
			frame.setResend(resend);
			frame.setStart(start);
			frame.setAmount(amount);
			frame.setCal(cal);
			frame.setDays(days);
			
			// mailbox.clear();
			Transput transput;
			if((transput = postOffice.send(frame)) != null) {
				Frame[] recv = null;
				if (transput.await() == Transput.SUCCESS && (recv = transput.getRecv()) != null) {
					task.setCommSuccNum(task.getCommSuccNum() + 1);
					// Object message = null;
					for (Frame message : recv) {
						// while((message = mailbox.get()) != null) {
						if (message instanceof Ctrl93Frame) {
							Ctrl93Frame f = (Ctrl93Frame) message;
							if(frame.match(f)) {
								scnt += save(f);	
							} else {
								logger.warn(String.format("frame is not match when collect resident meter hour frozen data"));
								logger.warn(String.format("request frame[%d]:%s", frame.getFseq(), ArrayUtil.sprintf(frame.getBytes(), "%02X ")));
								logger.warn(String.format("request frame[%d]:%s", f.getFseq(), ArrayUtil.sprintf(f.getBytes(), "%02X ")));
							}
						} 
					}
				}
			} else {
				if(failCnt++ >= 3) {
					logger.info(String.format("the communication to %s is unsteadiness, so yield task now", con.getLogicAddr()));
					break; // for
				}
			}
		}
		task.setRunTimes(task.getRunTimes() + 1);
		if(!terminated) {
			task.setLastRunDate(Calendar.getInstance().getTime());
		}
		refreshTaskStat();
	}
	
	private int save(Ctrl93Frame frame) {
		int scnt = 0;
		for(VipMeterData vmd : frame.getVipMeterData()) {
			ResMeter rm = findByNo(vmd.getMtno());
			if(rm != null) {
				boolean succ = true;
				dataAccessor.beginTransaction();
				for (int hh = 0; hh < 24; hh++) {
					VipFrozenDataPo vfd = new VipFrozenDataPo();
					vfd.setMpId(rm.getMpId());
					vfd.setDate(frame.getDate());
					vfd.setPp(vmd.getValue(hh));
					if(dataAccessor.saveVipFrozenData(vfd) != 0) {
						succ = false;
						break;
					}
				}
				if(succ) {
					dataAccessor.commit();
				} else {
					dataAccessor.rollback();
				}
			}
		}
		return scnt;
	}
}
